home *** CD-ROM | disk | FTP | other *** search
/ PLAYymate for OS/2 / Playmate for OS2.iso / p4os2045 / rollball.c < prev    next >
Text File  |  1992-07-15  |  20KB  |  469 lines

  1. /***********************************************************************\
  2.  *                               RollBall                              *
  3.  * an OS/2 2.0 PM Game                                                 *
  4. \***********************************************************************/
  5.  
  6. #define INCL_WIN
  7. #define INCL_WINSYS
  8. #define INCL_WINPOINTERS
  9. #define INCL_DEV
  10. #define INCL_WINDIALOGS
  11.  
  12. #define INCL_DOSPROCESS
  13.  
  14. #include <os2.h>            /* PM header files */
  15. #include <stdlib.h>
  16. #include "Error.h"
  17. #include "RollBall.h"
  18.  
  19. MRESULT EXPENTRY BallWindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  20. MRESULT EXPENTRY AboutDialog(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  21. MRESULT EXPENTRY ScoreDialog(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  22.  
  23. HAB    hab;                /* PM anchor block handle */
  24. PSZ     pszErrMsg;                      /* Error message */
  25. TID     tidDT;                          /* Thread ID of drawing thread */
  26.  
  27. int    AreaX;                          /* X Position of game area */
  28. int    AreaY;                          /* Y Position of game area */
  29. int    AreaSizeX;                      /* Size of game area width in units */
  30. int    AreaSizeY;                      /* Size of game area height in units */
  31. BOOL    AreaActive=FALSE;        /* Game area active or not */
  32.  
  33. HWND    hwndFrame=NULLHANDLE;        /* Handle of frame window */
  34. HWND    hwndClient=NULLHANDLE;        /* Handle of client window */
  35.  
  36. HPOINTER    hptrCrossHair;        /* Pointer handle */
  37.  
  38. HDC    hdcMem;
  39. HPS    hpsMem;
  40. HBITMAP    hbmMem;
  41.  
  42. int main(void)
  43. {
  44. DEVOPENSTRUC    DcData={NULL,"DISPLAY",NULL,NULL,NULL,NULL,NULL,NULL,NULL};
  45. SIZEL           sizellogo={81,81};
  46. HMQ     hmq;                            /* Handle of message queue */
  47. QMSG    qmsg;                           /* Message queue */
  48. ULONG   flCreate = FCF_SYSMENU |        /* Frame creation control flags */
  49.             FCF_MINBUTTON | FCF_ICON | FCF_MENU |
  50.             FCF_TASKLIST | FCF_TITLEBAR | FCF_ACCELTABLE;
  51.  
  52. if((hab=WinInitialize(0))==0L)          /* Initialize window */
  53.     GEN_ERR(hab,hwndFrame,hwndClient);
  54.  
  55. Draw_Initialize();                      /* Initialize data of drawing thread */
  56.  
  57. if((hdcMem=DevOpenDC(hab,               /* Open memory device context for startup
  58.                                            OS/2 logo */
  59.     OD_MEMORY,
  60.     (PSZ)"*",
  61.     8L,
  62.     (PDEVOPENDATA)&DcData,
  63.     (HDC)NULL))==0L)
  64.     GEN_ERR(hab,hwndFrame,hwndClient);
  65.  
  66. if((hpsMem=GpiCreatePS(hab,             /* Generate a presenation space for startup logo */
  67.     hdcMem,
  68.     &sizellogo,
  69.     GPIA_ASSOC|PU_PELS))==0L)
  70.     GEN_ERR(hab,hwndFrame,hwndClient);
  71.  
  72. if((hbmMem=GpiLoadBitmap(hpsMem,        /* Load startup logo from ressource (EXE file) */
  73.     0L,
  74.     OS2LOGO,
  75.     0L,
  76.     0L))==0L)
  77.     GEN_ERR(hab,hwndFrame,hwndClient);
  78.  
  79. if((hmq=WinCreateMsgQueue(hab,0))==0L)  /* Initialize message queue */
  80.     GEN_ERR(hab,hwndFrame,hwndClient);
  81.  
  82. if(!WinRegisterClass(                   /* Register window class */
  83.     hab,                                /* Handle of anchor block */
  84.     (PSZ)"BallWindow",                  /* Window class name */
  85.     (PFNWP)BallWindowProc,              /* Address of window procedure */
  86.     CS_SIZEREDRAW,                      /* Class style */
  87.     0))                                 /* No extra window words */
  88.      GEN_ERR(hab,hwndFrame,hwndClient);
  89.  
  90. if((hwndFrame = WinCreateStdWindow(
  91.     HWND_DESKTOP,                       /* Desktop window is parent */
  92.     0,                                  /* STD. window styles */
  93.     &flCreate,                          /* Frame control flag */
  94.     "BallWindow",                       /* Client window class name */
  95.     "",                                 /* No window text */
  96.     0,                                  /* No special class style */
  97.     (HMODULE)0L,                        /* Resource is in .EXE file */
  98.     ID_WINDOW,                          /* Frame window identifier */
  99.                                         /* Client window handle */
  100.     &hwndClient))==0L) GEN_ERR(hab,hwndFrame,hwndClient);
  101.  
  102.                                         /* Set window title and center it */
  103. WinSetWindowText(hwndFrame,"RollBall - A Shareware Game for OS/2 2.0");
  104. AreaSizeY=WinQuerySysValue(HWND_DESKTOP,SV_CYTITLEBAR);
  105. AreaSizeY+=WinQuerySysValue(HWND_DESKTOP,SV_CYMENU);
  106. AreaSizeX=RB_SIZE*(RB_X-2);
  107. AreaSizeY+=RB_SIZE*(RB_Y-2)+2;
  108. AreaX=(WinQuerySysValue(HWND_DESKTOP,SV_CXSCREEN)/2)-(AreaSizeX/2);
  109. AreaY=(WinQuerySysValue(HWND_DESKTOP,SV_CYSCREEN)/2)-(AreaSizeY/2);
  110.  
  111. if(!WinSetWindowPos(hwndFrame,          /* Shows and activates frame */
  112.     HWND_TOP,                           /* window position, */
  113.                                         /* and size. */
  114.     AreaX,AreaY,AreaSizeX,AreaSizeY,
  115.     SWP_MOVE | SWP_ACTIVATE | SWP_SHOW | SWP_SIZE))
  116.     GEN_ERR(hab,hwndFrame,hwndClient);
  117.  
  118. while(WinGetMsg(hab,&qmsg,0UL,0UL,0UL))
  119.     WinDispatchMsg(hab,&qmsg);
  120. WinDestroyWindow(hwndFrame);            /* Close window */
  121. WinDestroyMsgQueue(hmq);                /* Close message queue */
  122. WinTerminate(hab);                      /* Terminale the application */
  123. exit(0);
  124. }
  125.  
  126. MRESULT EXPENTRY BallWindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  127. {
  128. switch( msg )
  129. {
  130. case WM_CREATE:
  131.     {
  132.     static ULONG        ThreadArg=0;    /* Drawing thread parameters */
  133.     static ULONG        ThreadFlags=0;  /* Create thread in running mode */
  134.     static ULONG        StackSize=8192; /* Set thread stack size */
  135.     static APIRET       rc;
  136.  
  137.     AreaActive=TRUE;                    /* Client window is active */
  138.     hptrCrossHair=WinLoadPointer(HWND_DESKTOP,0L,ID_POINTER);
  139.                                         /* Create drawing thread */
  140.     if(!(rc=DosCreateThread(&tidDT,     /* Thread ID */
  141.         (PFNTHREAD)Draw_Thread,         /* Pointer to thread */
  142.         ThreadArg,                      /* Thread arguments */
  143.         ThreadFlags,                    /* Thread flags */
  144.         StackSize)))                    /* Stack size */
  145.         DOS_ERR(rc,hwndFrame,hwndClient);
  146.     break;
  147.     }
  148.  
  149. case WM_USER:
  150.     {
  151.     HPS                 hps;
  152.     POINTL              bmarray[4];
  153.  
  154.                                         /* Now load startup logo bitmap */
  155.     bmarray[0].x=(RB_SIZE*(RB_X-2)/2-40); bmarray[0].y=(RB_SIZE*(RB_Y-2)/2-40);
  156.     bmarray[1].x=bmarray[0].x+81; bmarray[1].y=bmarray[0].y+81;
  157.     bmarray[2].x=bmarray[2].y=0; bmarray[3].x=bmarray[3].y=80;
  158.     hps=WinGetPS(hwnd);
  159.     GpiSetBitmap(hpsMem,hbmMem);
  160.     if(!GpiSetBitmap(hps,
  161.         hbmMem)) GEN_ERR(hab,hwndFrame,hwndClient);
  162.     if(!GpiBitBlt(hps,
  163.         hpsMem,
  164.         4L,
  165.         (PPOINTL)bmarray,
  166.         ROP_SRCCOPY,
  167.         BBO_IGNORE)) GEN_ERR(hab,hwndFrame,hwndClient);
  168.     WinReleasePS(hps);
  169.     break;
  170.     }
  171. case WM_BUTTON1DOWN:
  172.     {
  173.                                         /* Set focus */
  174.     if(!WinSetFocus(HWND_DESKTOP,hwnd)) GEN_ERR(hab,hwndFrame,hwndClient);
  175.                                         /* Send lbutton with mouse position in device
  176.                                            coordinates, which are in mp1, but only if
  177.                                            RollBall is rolling */
  178.     if(runRB==TRUE) WinPostQueueMsg(hmqDT,
  179.         DT_LBUTTON,
  180.         MPFROMLONG(SHORT1FROMMP(mp1)),
  181.         MPFROMLONG(SHORT2FROMMP(mp1)));
  182.     break;
  183.     }
  184.  
  185. case WM_BUTTON2DOWN:
  186.     {
  187.                                         /* Set focus */
  188.     if(!WinSetFocus(HWND_DESKTOP,hwnd)) GEN_ERR(hab,hwndFrame,hwndClient);
  189.                                         /* Send rbutton with mouse position in device
  190.                                            coordinates, which are in mp1, but only if
  191.                                            RollBall is rolling */
  192.     if(runRB==TRUE) WinPostQueueMsg(hmqDT,
  193.         DT_RBUTTON,
  194.         MPFROMLONG(SHORT1FROMMP(mp1)),
  195.         MPFROMLONG(SHORT2FROMMP(mp1)));
  196.     break;
  197.     }
  198.  
  199. case WM_FOCUSCHANGE:
  200.     {
  201.     static BOOL runRBsave=2;
  202.  
  203.     if(SHORT1FROMMP(mp2)==TRUE)         /* TRUE if receiving focus */
  204.         {
  205.         WinSetPointer(HWND_DESKTOP,hptrCrossHair);
  206.                                         /* Restore RollBall's rolling indicator, but only
  207.                                            if it is valid */
  208.         if(runRBsave!=2) runRB=runRBsave;
  209.         }
  210.  
  211.     if(SHORT1FROMMP(mp2)==FALSE)        /* FALSE if losing focus */
  212.                                         /* We should stop RollBall from rolling only, if
  213.                                            a window is gaining focus, that is not a child
  214.                                            of our frame window */
  215.         if((WinIsChild(HWNDFROMMP(mp1),hwndFrame)==FALSE))
  216.             {
  217.             runRBsave=runRB;
  218.             runRB=FALSE;                /* If switching to another window stop RollBall */
  219.             }
  220.     return((MRESULT)WinDefWindowProc(hwnd,msg,mp1,mp2));
  221.     break;
  222.     }
  223.  
  224. case WM_MOUSEMOVE:
  225.     {
  226.     if(AreaActive==TRUE)
  227.         WinSetPointer(HWND_DESKTOP,hptrCrossHair);
  228.     break;
  229.     }
  230.  
  231. case WM_MINMAXFRAME:                    /* Adjust titlebar text according to minimize/
  232.                                            restore */
  233.     {
  234.     static BOOL runRBsave=FALSE;
  235.                                         /* If size is smaller than the playing ground is
  236.                                            set, then it must be minimized, because the
  237.                                            playing ground has no sizing border */
  238.     if(((PSWP)mp1)->fl & SWP_MINIMIZE)
  239.         {
  240.         WinSetWindowText(hwndFrame,"RollBall");
  241.                                         /* If RollBall is rolling, stop it */
  242.         if((runRBsave=runRB)==TRUE) runRB=FALSE;
  243.         }
  244.     else
  245.         {
  246.         WinSetWindowText(hwndFrame,"RollBall - A Shareware Game for OS/2 2.0");
  247.         runRB=runRBsave;                /* Restore rolling indicator to state before
  248.                                            minimized */
  249.         }
  250.     return((MRESULT)WinDefWindowProc(hwnd,msg,mp1,mp2));
  251.     break;
  252.     }
  253.  
  254. case WM_COMMAND:
  255.     {
  256.     USHORT command;                     /* WM_COMMAND command value */
  257.  
  258.     command=SHORT1FROMMP(mp1);          /* Extract the command value */
  259.     switch (command)
  260.         {
  261.     case ID_ABOUT:                      /* About RollBall dialog box selected */
  262.         {
  263.         BOOL    runRBsave;
  264.                                         /* If RollBall is rolling, stop it */
  265.         if((runRBsave=runRB)==TRUE) runRB=FALSE;
  266.         if(!WinDlgBox(HWND_DESKTOP,     /* Place on DESKTOP */
  267.             hwndFrame,                  /* Ownd by Frame window */
  268.             AboutDialog,                /* Implementing procedure */
  269.             (HMODULE)0,                 /* Resouce in EXE file */
  270.             ID_ABOUTDIALOG,             /* Dialog identifier in ressource */
  271.                                         /* No initialization data */
  272.             NULL)) GEN_ERR(hab,hwndFrame,hwndClient);
  273.         runRB=runRBsave;                /* Restore RollBall rolling indicator */
  274.         break;
  275.         }
  276.     case ID_SCORE:                      /* About Score dialog box selected */
  277.         {
  278.         BOOL    runRBsave;
  279.                                         /* If RollBall is rolling, stop it */
  280.         if((runRBsave=runRB)==TRUE) runRB=FALSE;
  281.         if(!WinDlgBox(HWND_DESKTOP,     /* Place on DESKTOP */
  282.             hwndFrame,                  /* Ownd by Frame window */
  283.             ScoreDialog,                /* Implementing procedure */
  284.             (HMODULE)0,                 /* Resouce in EXE file */
  285.             ID_SCOREDIALOG,             /* Dialog identifier in ressource */
  286.                                         /* No initialization data */
  287.             NULL)) GEN_ERR(hab,hwndFrame,hwndClient);
  288.         runRB=runRBsave;                /* Restore RollBall rolling indicator */
  289.         break;
  290.         }
  291.     case ID_STARTTHREAD:                /* Start the game */
  292.         {
  293.         HWND    hwndMenu;
  294.                                         /* Get window handle of menu bar */
  295.         if((hwndMenu=WinWindowFromID(hwndFrame,FID_MENU))==NULLHANDLE)
  296.             GEN_ERR(hab,hwndFrame,hwndClient);
  297.         if((WinSendMsg(hwndMenu,        /* Disable start item */
  298.             MM_SETITEMATTR,
  299.             MPFROM2SHORT(ID_STARTTHREAD,TRUE),
  300.             MPFROM2SHORT(MIA_DISABLED,MIA_DISABLED)))==FALSE)
  301.             GEN_ERR(hab,hwndFrame,hwndClient);
  302.         if((WinSendMsg(hwndMenu,        /* Enable pause item */
  303.             MM_SETITEMATTR,
  304.             MPFROM2SHORT(ID_PAUSETHREAD,TRUE),
  305.             MPFROM2SHORT(MIA_DISABLED,0)))==FALSE)
  306.             GEN_ERR(hab,hwndFrame,hwndClient);
  307.         if((WinSendMsg(hwndMenu,        /* Enable stop item */
  308.             MM_SETITEMATTR,
  309.             MPFROM2SHORT(ID_STOPTHREAD,TRUE),
  310.             MPFROM2SHORT(MIA_DISABLED,0)))==FALSE)
  311.             GEN_ERR(hab,hwndFrame,hwndClient);
  312.         Playground_Initialize();        /* Initialize playing ground with 50 symbols */
  313.         WinInvalidateRegion(hwnd,NULLHANDLE,FALSE);
  314.         runRB=TRUE;                     /* RollBall is rolling */
  315.         break;
  316.         }
  317.     case ID_STOPTHREAD:                 /* Stop the game */
  318.         {
  319.         HWND            hwndMenu;
  320.         unsigned char   MsgBuffer[512];
  321.  
  322.                                         /* Get window handle of menu bar */
  323.         if((hwndMenu=WinWindowFromID(hwndFrame,FID_MENU))==NULLHANDLE)
  324.             GEN_ERR(hab,hwndFrame,hwndClient);
  325.         if((WinSendMsg(hwndMenu,        /* Disable the stop item */
  326.             MM_SETITEMATTR,
  327.             MPFROM2SHORT(ID_STOPTHREAD,TRUE),
  328.             MPFROM2SHORT(MIA_DISABLED,MIA_DISABLED)))==FALSE)
  329.             GEN_ERR(hab,hwndFrame,hwndClient);
  330.         if((WinSendMsg(hwndMenu,        /* Disable the pause item */
  331.             MM_SETITEMATTR,
  332.             MPFROM2SHORT(ID_PAUSETHREAD,TRUE),
  333.             MPFROM2SHORT(MIA_DISABLED,MIA_DISABLED)))==FALSE)
  334.             GEN_ERR(hab,hwndFrame,hwndClient);
  335.         if((WinSendMsg(hwndMenu,        /* Enable the start item */
  336.             MM_SETITEMATTR,
  337.             MPFROM2SHORT(ID_STARTTHREAD,TRUE),
  338.             MPFROM2SHORT(MIA_DISABLED,0)))==FALSE)
  339.             GEN_ERR(hab,hwndFrame,hwndClient);
  340.         runRB=FALSE;                    /* RollBall is not rolling */
  341.         sprintf(MsgBuffer,"Thank you for playing RollBall!\n"\
  342.             "Your score is %d point(s)!\nHope you'd a good time!\n\n"\
  343.             "If you find this game valuable, or you have any suggestions to "\
  344.             "improve this game, let me know. (Please see RollBall.doc for "\
  345.             "details)",RB_Point[0]);
  346.         WinMessageBox(HWND_DESKTOP,     /* Inform the user about the points */
  347.             hwndFrame,                  /* Ownder window */
  348.             (PSZ)MsgBuffer,             /* Message */
  349.             "RollBall Score Info",      /* Title bar message */
  350.             61324,                      /* Message identifier (is random and unique) */
  351.             MB_INFORMATION | MB_OK);
  352.         break;
  353.         }
  354.     case ID_PAUSETHREAD:                /* Pause/unpause the game */
  355.         {
  356.         HWND            hwndMenu;
  357.         static int      pauseOn=FALSE;
  358.         MRESULT         rc;
  359.                                         /* Get window handle of menu bar */
  360.         if((hwndMenu=WinWindowFromID(hwndFrame,FID_MENU))==NULLHANDLE)
  361.             GEN_ERR(hab,hwndFrame,hwndClient);
  362.         if(pauseOn==TRUE)
  363.             {
  364.             runRB=TRUE;                 /* RollBall should be rolling */
  365.             rc=WinSendMsg(hwndMenu,     /* Change unpause item to pause */
  366.                 MM_SETITEMTEXT,
  367.                 MPFROMLONG(ID_PAUSETHREAD),
  368.                 MPFROMP("~Pause Game"));
  369.             if(rc==FALSE) USR_ERR("MM_SETITEMTEXT failed\n");
  370.             GEN_ERR(hab,hwndFrame,hwndClient);
  371.             }
  372.         else
  373.             {
  374.             runRB=FALSE;                /* RollBall should be rolling */
  375.             rc=WinSendMsg(hwndMenu,     /* Change to pause item to unpause */
  376.                 MM_SETITEMTEXT,
  377.                 MPFROMLONG(ID_PAUSETHREAD),
  378.                 MPFROMP("~Unpause Game"));
  379.             if(rc==FALSE) USR_ERR("MM_SETITEMTEXT failed\n");
  380.             GEN_ERR(hab,hwndFrame,hwndClient);
  381.             }
  382.         pauseOn=(pauseOn==TRUE ? FALSE : TRUE);
  383.         break;
  384.         }
  385.     case ID_EXITPROGRAM:
  386.         WinPostMsg(hwnd,WM_CLOSE,(MPARAM)0,(MPARAM)0);
  387.         break;
  388.     default:
  389.         return((MRESULT)WinDefWindowProc(hwnd,msg,mp1,mp2));
  390.         }
  391.     break;
  392.     }
  393.  
  394. case WM_PAINT:
  395.     {
  396.     static BOOL         logoinit=TRUE;
  397.     static HPS          hps;        /* Handle of a presentaion space */
  398.  
  399.                                         /* Create a presentation space, even if don't
  400.                                            paint here, this call prevents us that endless
  401.                                            WM_PAINT messages are generated  */
  402.     hps = WinBeginPaint(hwnd,
  403.         NULLHANDLE,                     /* Presentation space (a chached) */
  404.         NULL);                          /* Bounding rectangle (none, no painting required) */
  405.                                         /* Send paint to drawing thread */
  406.                                         /* Repaint client window aread */
  407.     WinPostQueueMsg(hmqDT,DT_PAINT,0UL,0UL);
  408.     WinEndPaint(hps);                   /* Release presenation space */
  409.     if(logoinit==TRUE)                  /* Display logo only at startup */
  410.         {
  411.         logoinit=FALSE;                 /* Disable logo for further repaints */
  412.         DosSleep(50);                   /* Force pre-emting to second thread to clear
  413.                                            window to white */
  414.                                         /* Display startup logo */
  415.         WinPostMsg(hwnd,WM_USER,NULL,NULL);
  416.         }
  417.     break;
  418.     }
  419. case WM_CLOSE:
  420.                                         /* Post exit to drawing thread */
  421.     WinPostQueueMsg(hmqDT,DT_EXIT,0UL,0UL);
  422.                                         /* Wait for shutdown of drawing thread */
  423.     DosWaitThread(&tidDT,DCWW_WAIT);
  424.     WinPostMsg(hwnd,WM_QUIT,NULL,NULL);
  425.     break;
  426.  
  427. default:
  428.     return((MRESULT)WinDefWindowProc(hwnd, msg, mp1, mp2));
  429. }
  430. return((MRESULT)FALSE);
  431. }
  432.  
  433. /***********************************************************************\
  434.  *                               RollSub1                              *
  435.  * About Dialog routine for RollBall                                   *
  436. \***********************************************************************/
  437.  
  438. MRESULT EXPENTRY AboutDialog(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  439. {
  440. switch(msg)
  441. {
  442. case WM_COMMAND:                        /* Clear About dialog box */
  443.     WinDismissDlg(hwnd, TRUE);
  444.     break;
  445. default:
  446.     return(WinDefDlgProc(hwnd,msg,mp1,mp2));
  447. }
  448. return((MRESULT)0);
  449. }
  450.  
  451. /***********************************************************************\
  452.  *                               RollSub1                              *
  453.  * Score Dialog routine for RollBall                                   *
  454. \***********************************************************************/
  455.  
  456. MRESULT EXPENTRY ScoreDialog(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  457. {
  458. switch(msg)
  459. {
  460. case WM_COMMAND:                        /* Clear Score dialog box */
  461.     WinDismissDlg(hwnd, TRUE);
  462.     break;
  463. default:
  464.     return(WinDefDlgProc(hwnd,msg,mp1,mp2));
  465. }
  466. return((MRESULT)0);
  467. }
  468.  
  469.